package com.loe.ktui

import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.ScrollView
import androidx.core.content.res.getBooleanOrThrow
import androidx.core.content.res.getDimensionOrThrow
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.loe.ktui.util.KtColor
import com.loe.ktui.util.KtCornerProvider

open class UiScrollView(id: String? = null) : UiGroup(id)
{
    var scrollBarSize: Any? = null
    var overScrollMode: Int? = null
    var fillViewport: Boolean? = null
    var isRefresh: Boolean? = null
    var refreshColor: Int? = null

    var onRefresh: (KtScrollView.()->Unit)? = null
    fun onRefresh(onRefresh: KtScrollView.()->Unit)
    {
        this.onRefresh = onRefresh
    }

    var onScroll: (KtScrollView.(t: Int)->Unit)? = null
    fun onScroll(onScroll: KtScrollView.(t: Int)->Unit)
    {
        this.onScroll = onScroll
    }

    open fun initUI(context: Context, view: KtScrollView)
    {
        super.initUI(context, view)

        isAlphaClick?.let { view.isAlphaClick = it }

        maxHeight?.let { view.maxHeight = it.dist }
        fillViewport?.let { view.isFillViewport = it }
        isRefresh?.let {
            view.isEnableRefresh = it
            if (!it)
            {
                view.refreshLayout?.setOnClickListener(null)
                view.refreshLayout = null
            }
        }

        scrollBarSize?.let { view.scrollBarSize = it.dist }
        overScrollMode?.let { view.overScrollMode = it }

        refreshColor?.let {
            view.refreshColor = it
            view.refreshLayout?.setColorSchemeColors(it)
        }

        onRefresh?.let { on -> view.onRefresh = { view.on() } }
        onScroll?.let { on -> view.onScroll = { view.on(it) } }

        // 递归子元素
        childs.forEach()
        {
            it.createView(context, view)
        }
    }

    /** 创建view */
    override fun createView(context: Context, parent: ViewGroup?): KtScrollView
    {
        return KtScrollView(context).also()
        {
            initUI(context, it)
            addToParent(parent, it)
        }
    }
}

fun Any.ui_ScrollView(id: String? = null, block: (UiScrollView.() -> Unit)? = null): UiScrollView
{
    val ui = UiScrollView(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

open class KtScrollView : ScrollView
{
    constructor(context: Context) : super(context)
    {
        initXML()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtScrollView))
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtScrollView, defStyleAttr, 0))
    }

    private fun initXML(typedArray: TypedArray? = null)
    {
        typedArray?.let()
        {
            if (it.hasValue(R.styleable.KtScrollView_kt_corner))
            {
                val corner = it.getDimensionOrThrow(R.styleable.KtScrollView_kt_corner).toInt()
                val cornerDirect =  KtDirects[it.getInt(R.styleable.KtScrollView_kt_cornerDirect, 4)]

                outlineProvider = KtCornerProvider(corner, cornerDirect, this)
            }
            if (it.hasValue(R.styleable.KtScrollView_kt_isAlphaClick))
            {
                isAlphaClick = it.getBooleanOrThrow(R.styleable.KtScrollView_kt_isAlphaClick)
            }

            if (it.hasValue(R.styleable.KtScrollView_kt_maxHeight))
            {
                maxHeight = it.getDimensionOrThrow(R.styleable.KtScrollView_kt_maxHeight).toInt()
            }

            it.recycle()
        }
    }

    /********************************************** 点击 ****************************************/

    var isAlphaClick = false
        set(value)
        {
            field = value
            isClickable = value
        }

    override fun dispatchSetPressed(pressed: Boolean)
    {
        if (isAlphaClick) alpha = if (pressed || !isEnabled) 0.75f else 1f
        super.dispatchSetPressed(pressed)
    }

    override fun setEnabled(enabled: Boolean)
    {
        if (isAlphaClick) alpha = if (enabled) 1f else 0.75f
        super.setEnabled(enabled)
    }

    /*****************************************   滚动   ****************************************/

    var onScroll: ((t: Int)->Unit)? = null

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int)
    {
        super.onScrollChanged(l, t, oldl, oldt)
        onScroll?.invoke(t)
    }

    fun getScrollHeight(): Int
    {
        return try
        {
            getChildAt(0).height - height
        }catch (e: Exception)
        {
            0
        }
    }

    /***************************************** 加载刷新 ****************************************/

    internal var refreshColor: Int? = null

    /** 刷新View */
    var refreshLayout: SwipeRefreshLayout? = null
        set(value)
        {
            if (isEnableRefresh)
            {
                field = value
                value?.isEnabled = true
                if (refreshColor != null)
                {
                    value?.setColorSchemeColors(refreshColor!!)
                } else
                {
                    value?.setColorSchemeColors(KtColor.main)
                }
                // 刷新监听
                value?.setOnRefreshListener()
                {
                    postDelayed({ onRefresh?.invoke() }, 400)
                }
            } else
            {
                field = null
            }
        }

    fun refresh()
    {
        refreshLayout?.measure(0, 0)
        refreshLayout?.isRefreshing = true
    }

    fun setRefreshing(refreshing: Boolean)
    {
        refreshLayout?.isRefreshing = refreshing
    }

    internal var isEnableRefresh = true

    /** 刷新监听 */
    var onRefresh: (() -> Unit)? = null

    internal var maxHeight = 0

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
    {
        var heightSpec = heightMeasureSpec
        if (maxHeight > 0)
        {
            heightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
        }
        super.onMeasure(widthMeasureSpec, heightSpec)
    }
}